package com.touchstone.cloudpacs.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.touchstone.cloudpacs.common.annotation.MonitorLog;
import com.touchstone.cloudpacs.common.constant.UserConstant;
import com.touchstone.cloudpacs.common.exception.BusinessException;
import com.touchstone.cloudpacs.common.utils.CommonUtils;
import com.touchstone.cloudpacs.common.utils.SqlUtils;
import com.touchstone.cloudpacs.common.utils.request.PageRequest;
import com.touchstone.cloudpacs.entity.User;
import com.touchstone.cloudpacs.enums.StatusEnum;
import com.touchstone.cloudpacs.mapper.UserMapper;
import com.touchstone.cloudpacs.request.UserRequest;
import com.touchstone.cloudpacs.request.query.UserPageQuery;
import com.touchstone.cloudpacs.service.IUserService;
import com.touchstone.cloudpacs.vo.UserPageVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import javax.servlet.http.HttpSession;
import java.util.Date;

/**
 * @Description : 用户业务实现层
 * @Author : hunter
 * @Date: 2019-07-11 23:28
 * @Version: 1.0
 **/
@Slf4j
@Service
public class UserServiceImpl extends BaseServiceImpl implements IUserService {

    @Autowired
    private UserMapper mapper;
    @Autowired
    private HttpSession session;

    /**
     * 盐值
     */
    private static final String SALT = "xsh72f8ds37k@83-9112&kksdn";
    /**
     * 加密次数
     */
    private static final int ENCRYPTION_TIMES = 5;

    @Override
    @MonitorLog("新增用户")
    @Transactional(rollbackFor = Exception.class)
    public User save(UserRequest request) {
        if (mapper.selectByUserName(request.getUserName()) != null) {
            throw new BusinessException("已存在相同用户名的用户，请更换用户名");
        }
        User user = new User();
        BeanUtils.copyProperties(request, user);
        user.setId(CommonUtils.getUuid());
        user.setPassword(encodeByMd5(request.getPassword()));
        user.setCreateUserId(getCurrentUser().getId());
        user.setCreateTime(new Date());
        int record = mapper.insert(user);
        if (record > 0) {
            log.info("新增用户:{}", user);
        }
        return record > 0 ? user : null;
    }

    @Override
    @MonitorLog("修改用户")
    @Transactional(rollbackFor = Exception.class)
    public User update(UserRequest userRequest) {
        User user = get(userRequest.getId());
        if (mapper.selectByUserName(userRequest.getUserName()) != null && !userRequest.getUserName().equals(user.getUserName())) {
            throw new BusinessException("已存在相同用户名的用户，请更换用户名");
        }
        BeanUtils.copyProperties(userRequest, user);
        user.setLastUpdateUserId(getCurrentUser().getId());
        user.setLastUpdateTime(new Date());
        user.setPassword(encodeByMd5(user.getPassword()));
        int record = mapper.update(user);
        if (record > 0) {
            log.info("更新用户:{}", user);
        }
        return record > 0 ? user : null;
    }

    @Override
    @MonitorLog("禁用用户")
    @Transactional(rollbackFor = Exception.class)
    public int disabled(String id) {
        User user = new User();
        user.setId(id);
        user.setStatus(StatusEnum.DISABLED.getCode());
        user.setLastUpdateUserId(getCurrentUser().getId());
        user.setLastUpdateTime(new Date());
        int record = mapper.updateStatus(user);
        if (record > 0) {
            log.info("禁用ID为 {} 的用户。", id);
        }
        return record;
    }

    @Override
    @MonitorLog("启用用户")
    @Transactional(rollbackFor = Exception.class)
    public int enable(String id) {
        User user = new User();
        user.setId(id);
        user.setStatus(StatusEnum.NORMAL.getCode());
        user.setLastUpdateUserId(getCurrentUser().getId());
        user.setLastUpdateTime(new Date());
        int record = mapper.updateStatus(user);
        if (record > 0) {
            log.info("启用ID为 {} 的用户。", id);
        }
        return record;
    }

    @Override
    public User get(String id) {
        User user = mapper.selectById(id);
        log.info("查询用户：{} ", user);
        return user;
    }

    @Override
    public PageInfo<UserPageVO> selectByPage(PageRequest<UserPageQuery> pageRequest) {
        log.info("分页查询用户，查询条件：{} ", pageRequest);
        if (CommonUtils.isNotEmpty(pageRequest.getParam())) {
            //处理模糊查询中可能出现的特殊符号
            pageRequest.getParam().setUserName(SqlUtils.handleKeywordSpecialCharacter(pageRequest.getParam().getUserName()));
        }
        PageHelper.startPage(pageRequest.getPage(), pageRequest.getLimit(), pageRequest.getOrderBys());
        return new PageInfo<>(mapper.selectByQuery(pageRequest.getParam()));
    }

    @Override
    @MonitorLog("登录")
    @Transactional(rollbackFor = Exception.class)
    public void login(String userName, String password) {
        User user = mapper.selectByUserName(userName);
        if (user == null) {
            throw new BusinessException("不存在该账户");
        }
        if (encodeByMd5(password).equals(user.getPassword())) {
            log.info("用户：{} 登录 ", user);
            //存储到session中
            session.setAttribute(UserConstant.CURRENT_USER, user);
        } else {
            throw new BusinessException("账户与密码不匹配");
        }
    }

    @Override
    @MonitorLog("注销")
    @Transactional(rollbackFor = Exception.class)
    public void logout() {
        log.info("用户：{} 注销 ");
        if (session.getAttribute(UserConstant.CURRENT_USER) != null) {
            session.removeAttribute(UserConstant.CURRENT_USER);
        }
    }

    /**
     * MD5加密
     *
     * @param content 加密内容
     * @return String 加密后的字符串
     * @throws：
     * @createUserName: hunter
     * @createTime: 2019/7/14 20:54
     */
    private String encodeByMd5(String content) {
        //MD5加密
        for (int i = 0; i < ENCRYPTION_TIMES; i++) {
            content = DigestUtils.md5DigestAsHex((content + SALT).getBytes());
        }
        return content;
    }

}
